﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Utility.Utils.SnowflakeUtils
{
    /// <summary>
    /// 集成ID生产规则
    /// </summary>
    public class IdWorker : ReflectionSingleton<IdWorker>
    {
        /// <summary>
        /// 构造函数私有化
        /// </summary>
        private IdWorker() { }

        #region 获取格式化GUID
        public enum GuidType { N, D, B, P, X, Default };
        public enum IsToUpperOrToLower { ToUpper, ToLower };

        public string GetFormatGuid(GuidType guidType = GuidType.N, IsToUpperOrToLower isToUpperOrToLower = IsToUpperOrToLower.ToLower)
        {
            string guid = guidType switch
            {
                GuidType.N => Guid.NewGuid().ToString("N"), // e0a953c3ee6040eaa9fae2b667060e09 
                GuidType.D => Guid.NewGuid().ToString("D"), // 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
                GuidType.B => Guid.NewGuid().ToString("B"), // {734fd453-a4f8-4c5d-9c98-3fe2d7079760}
                GuidType.P => Guid.NewGuid().ToString("P"), // (ade24d16-db0f-40af-8794-1e08e2040df3)
                GuidType.X => Guid.NewGuid().ToString("X"), // (ade24d16-db0f-40af-8794-1e08e2040df3)
                GuidType.Default => Guid.NewGuid().ToString(), // {0x3fa412e3,0x8356,0x428f,{0xaa,0x34,0xb7,0x40,0xda,0xaf,0x45,0x6f}}
                _ => throw new NotImplementedException(),
            };

            switch (isToUpperOrToLower)
            {
                case IsToUpperOrToLower.ToUpper:
                    guid = guid.ToUpper(); //返回大写GUID
                    break;
                case IsToUpperOrToLower.ToLower:
                    guid = guid.ToLower(); //返回小写GUID
                    break;
            }
            return guid;
        }
        #endregion

        /// <summary>
        /// 获取机器唯一编码
        /// </summary>
        /// <returns></returns>
        public string GetMachineCodeString() => MachineCode.GetMachineCodeString();

        /// <summary>
        /// 获取分布式Id（Snowflake）
        /// </summary>
        /// <param name="prefix">业务标识前缀</param>
        /// <param name="machineId">机器Id（集群环境的服务器Id）</param>
        /// <param name="datacenterId">分布式数据中心Id（服务Id）</param>
        /// <param name="hasRandom">是否开启随机变量</param>
        /// <returns></returns>
        public string GetSnowflakeId(string prefix, short machineId, short datacenterId, bool hasRandom = true)
        {
            Snowflake.Instance.SnowflakesInit(machineId, datacenterId);
            string randomNo = GenerateRandomNumber(6);
            if (hasRandom)
            {
                if (string.IsNullOrWhiteSpace(prefix)) return $"{randomNo}.{Snowflake.Instance.NextId()}";
                else return $"{prefix}.{randomNo}.{Snowflake.Instance.NextId()}";
            }
            else
            {
                if (string.IsNullOrWhiteSpace(prefix)) return $"{Snowflake.Instance.NextId()}";
                else return $"{prefix}.{Snowflake.Instance.NextId()}";
            }
        }

        #region 获取随机数
        /// <summary>
        /// 随机数基础数据
        /// </summary>
        private readonly char[] _RandomBasicData =
        {
            '0','1','2','3','4','5','6','7','8','9',
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
        };

        /// <summary>
        /// 生产随机数
        /// </summary>
        /// <param name="length">随机数长度</param>
        /// <returns></returns>
        public string GenerateRandomNumber(int length)
        {
            int capacity = _RandomBasicData.Length;
            StringBuilder newRandom = new StringBuilder(capacity);
            Random rd = new Random();
            for (int i = 0; i < length; i++)
            {
                newRandom.Append(_RandomBasicData[rd.Next(capacity)]);
            }
            return newRandom.ToString();
        }
        #endregion
    }
}
